<?php
/**
 * @copyright Copyright (c) 2019
 */

namespace lujie\proxy;


class Socks5Helper
{
    public const ADDR_TYPE_IPV4 = 1;
    public const ADDR_TYPE_IPV6 = 4;
    public const ADDR_TYPE_HOST = 3;

    /**
     * @param string $buffer
     * @return array|null
     */
    public static function parseHeader(string $buffer): ?array
    {
        $addr_type = ord($buffer[3]);
        switch ($addr_type) {
            case self::ADDR_TYPE_IPV4:
                if (strlen($buffer) < 10) {
                    echo bin2hex($buffer) . "\n";
                    echo "buffer too short\n";
                    return null;
                }
                $dest_addr = ord($buffer[4]) . '.' . ord($buffer[5]) . '.' . ord($buffer[6]) . '.' . ord($buffer[7]);
                $port_data = unpack('n', substr($buffer, -2));
                $dest_port = $port_data[1];
                $header_length = 10;
                break;
            case self::ADDR_TYPE_HOST:
                $addrLen = ord($buffer[4]);
                if (strlen($buffer) < $addrLen + 5) {
                    echo $buffer . "\n";
                    echo bin2hex($buffer) . "\n";
                    echo "buffer too short\n";
                    return null;
                }
                $dest_addr = substr($buffer, 5, $addrLen);
                $port_data = unpack('n', substr($buffer, -2));
                $dest_port = $port_data[1];
                $header_length = $addrLen + 7;
                break;
            case self::ADDR_TYPE_IPV6:
                if (strlen($buffer) < 22) {
                    echo "buffer too short\n";
                    return null;
                }
                echo "todo ipv6\n";
                return null;
            default:
                echo "unsupported addrtype $addr_type\n";
                return null;
        }
        return [$addr_type, $dest_addr, $dest_port, $header_length];
    }
}